﻿using System;
using System.IO;
using System.Xml;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Qpm.Automap.Core.UI
{
  public partial class Form1 : Form
  {
    private string m_importFile;
    private string m_exportFile;
    private string m_configFile;
    private string m_projectName;
    private string m_applicationDirectory;
    private string m_projectContractFile = "ContractInfo.xml";
    private string m_tempDirName = "TempFiles";
    private string m_configDirName = "Project Configurations";

    public Form1()
    {
      InitializeComponent();
      m_applicationDirectory = Application.StartupPath;
      m_projectContractFile = Path.Combine(m_applicationDirectory, m_projectContractFile);
      m_tempDirName = Path.Combine(m_applicationDirectory, m_tempDirName);
      m_configDirName = Path.Combine(m_applicationDirectory, m_configDirName);
      dgv_Tasks.DataBindingComplete += new DataGridViewBindingCompleteEventHandler(dgv_Tasks_DataBindingComplete);
    }

    void dgv_Tasks_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
    {
      styleTaskGrid();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      openFileDialog1.ShowDialog();

      if (!Directory.Exists(m_tempDirName))
      {
        Directory.CreateDirectory(m_tempDirName);
      }

      if (!Directory.Exists(m_configDirName))
      {
        Directory.CreateDirectory(m_configDirName);
      }

      m_importFile = openFileDialog1.FileName;
      m_projectName = Path.GetFileNameWithoutExtension(m_importFile);
      m_exportFile = Path.Combine(m_tempDirName, m_projectName + ".xml");
      m_configFile = Path.Combine(m_configDirName, m_projectName + ".xml");

      l_status.Text = "Creating temporary project xml file";
      progressBar1.Value = 20;
      ProjectAutomator.ConvertMppToXml(m_importFile, m_exportFile);

      l_status.Text = "Retrieving contract info from configuration files";
      progressBar1.Value = 40;
      DataTable contractTable = GetContractInfo(m_projectName);
      dgv_contractInfo.DataSource = contractTable;
      dgv_contractInfo.Columns[0].ReadOnly = true;

      l_status.Text = "Populating Project Task and Resource information";
      progressBar1.Value = 60;
      DataTable tasks = ProjectReader.GetProjectTasks(m_exportFile);
      DataTable resources = ProjectReader.GetProjectResources(m_exportFile);

      SelectTasksInConfig(tasks);
      SelectResourcesInConfig(resources);

      dgv_Tasks.DataSource = tasks;
      dgv_Resources.DataSource = resources;

      dgv_Tasks.Columns[0].Width = 40;
      dgv_Resources.Columns[0].Width = 40;
      dgv_Resources.Columns["UID"].Visible = false;

      for(int i = 1; i<dgv_Tasks.Columns.Count; i++)
      {
        dgv_Tasks.Columns[i].ReadOnly=true;
        if (i > 3)
        {
          dgv_Tasks.Columns[i].Visible = false;
        }
      }
      dgv_Tasks.Columns[1].Width = 40;
      dgv_Tasks.Columns[1].HeaderText = "";
      dgv_Resources.Columns[1].HeaderText = "";
      dgv_Tasks.Columns[3].Width = 300;

      for (int i = 1; i < dgv_Resources.Columns.Count; i++)
      {
        dgv_Resources.Columns[i].ReadOnly = true;
      }


      comboBox1.SelectedIndex = 2;

      l_status.Text = "Deleting temporary files";
      progressBar1.Value = 90;
      File.Delete(m_exportFile);
      button2.Enabled = true;
      progressBar1.Value = 100;
      l_status.Text = "Project finished loading";
    }

    private void button2_Click(object sender, EventArgs e)
    {
      XmlDocument xdoc = new XmlDocument();
      if (File.Exists(m_configFile))
      {
        xdoc.Load(m_configFile);
      }
      else
      {
        XmlElement projectElement = xdoc.CreateElement("Project");
        XmlAttribute nameAttribute = xdoc.CreateAttribute("Name");
        nameAttribute.Value = m_projectName;
        projectElement.Attributes.Append(nameAttribute);
        xdoc.AppendChild(projectElement);
      }

      InsertContractInfoData(xdoc);
      InsertSelectedTasks(xdoc);
      InsertSelectedResources(xdoc);

      xdoc.Save(m_configFile);
    }

    private void InsertContractInfoData(XmlDocument xdoc)
    {
      string contractNodeName = "ContractInfo";
      XmlElement contractInfoNode = xdoc.DocumentElement.SelectSingleNode("//" + contractNodeName) as XmlElement;
      if (contractInfoNode == null)
      {
        contractInfoNode = xdoc.CreateElement(contractNodeName);
        xdoc.DocumentElement.AppendChild(contractInfoNode);
      }
      DataTable contractsTable = dgv_contractInfo.DataSource as DataTable;
      foreach (DataRow row in contractsTable.Rows)
      {
        XmlElement fieldNode;
        string fieldName = row["FieldName"].ToString();

        fieldNode = xdoc.SelectSingleNode("//" + contractNodeName + "/Field[@Name='" + fieldName + "']") as XmlElement;
        if (fieldNode == null)
        {
          fieldNode = xdoc.CreateElement("Field");
          XmlAttribute fieldNameAtt = xdoc.CreateAttribute("Name");
          fieldNameAtt.Value = fieldName;
          fieldNode.Attributes.Append(fieldNameAtt);
          contractInfoNode.AppendChild(fieldNode);
        }
        fieldNode.InnerText = row["Value"].ToString();
      }
    }

    private void InsertSelectedTasks(XmlDocument xdoc)
    {
      string sTaskNodeName = "SelectedTasks";
      XmlElement sTaskNode = xdoc.DocumentElement.SelectSingleNode("//" + sTaskNodeName) as XmlElement;
      if (sTaskNode == null)
      {
        sTaskNode = xdoc.CreateElement(sTaskNodeName);
        xdoc.DocumentElement.AppendChild(sTaskNode);
      }
      else
      {
        sTaskNode.RemoveAll();
      }
      DataTable taskTable = dgv_Tasks.DataSource as DataTable;
      DataRow[] tasks = taskTable.Select("Select <> 0");
      foreach (DataRow row in tasks)
      {
        XmlElement uidElement = xdoc.CreateElement("TaskUID");
        uidElement.InnerText = row["UID"].ToString();
        sTaskNode.AppendChild(uidElement);
      }
    }

    private void InsertSelectedResources(XmlDocument xdoc)
    {
      string sResNodeName = "SelectedResources";
      XmlElement sResNode = xdoc.DocumentElement.SelectSingleNode("//" + sResNodeName) as XmlElement;
      if (sResNode == null)
      {
        sResNode = xdoc.CreateElement(sResNodeName);
        xdoc.DocumentElement.AppendChild(sResNode);
      }
      else
      {
        sResNode.RemoveAll();
      }
      DataTable resTable = dgv_Resources.DataSource as DataTable;
      DataRow[] resources = resTable.Select("Select <> 0");
      foreach (DataRow row in resources)
      {
        XmlElement uidElement = xdoc.CreateElement("ResUID");
        uidElement.InnerText = row["UID"].ToString();
        sResNode.AppendChild(uidElement);
      }
    }

    private DataTable GetContractInfo(string projectName)
    {
      XmlDocument fieldsDoc = new XmlDocument();
      fieldsDoc.Load(m_projectContractFile);

      DataTable contractTable = new DataTable();
      contractTable.Columns.Add("FieldName", typeof(string));
      contractTable.Columns.Add("Value", typeof(string));

      XmlNodeList fieldNodes = fieldsDoc.SelectNodes("//ContractFields/Field");

      bool configExists = false;
      XmlDocument configDoc = new XmlDocument();
      if (File.Exists(m_configFile))
      {
        configExists = true;
        configDoc.Load(m_configFile);
      }

      foreach (XmlElement fieldNode in fieldNodes)
      {
        DataRow row = contractTable.NewRow();
        string fieldName = fieldNode.Attributes["Name"].Value;

        if (configExists)
        {
          XmlNode contractNode = configDoc.SelectSingleNode("//ContractInfo/Field[@Name='" + fieldName + "']");
          row["Value"] = contractNode == null ? string.Empty : contractNode.InnerText;
        }
        row["FieldName"] = fieldName;
        contractTable.Rows.Add(row);
      }

      return contractTable;
    }

    private void SelectTasksInConfig(DataTable taskTable)
    {
      if (!File.Exists(m_configFile))
        return;

      XmlDocument xdoc = new XmlDocument();
      xdoc.Load(m_configFile);

      XmlNodeList taskNodes = xdoc.SelectNodes("//SelectedTasks/TaskUID");
      foreach (XmlElement taskElement in taskNodes)
      {
        int taskUid = taskElement.InnerText == null || taskElement.InnerText.Trim().Length == 0 ? -1 : Convert.ToInt32(taskElement.InnerText);
        if (taskUid<0)
          continue;
        DataRow[] taskRows = taskTable.Select("UID = " + taskUid.ToString());
        foreach (DataRow taskRow in taskRows)
        {
          taskRow["Select"] = true;
        }
      }
    }

    private void SelectResourcesInConfig(DataTable resTable)
    {
      if (!File.Exists(m_configFile))
        return;

      XmlDocument xdoc = new XmlDocument();
      xdoc.Load(m_configFile);

      XmlNodeList taskNodes = xdoc.SelectNodes("//SelectedResources/ResUID");
      foreach (XmlElement taskElement in taskNodes)
      {
        int taskUid = taskElement.InnerText == null || taskElement.InnerText.Trim().Length == 0 ? -1 : Convert.ToInt32(taskElement.InnerText);
        if (taskUid < 0)
          continue;
        DataRow[] taskRows = resTable.Select("UID = " + taskUid.ToString());
        foreach (DataRow taskRow in taskRows)
        {
          taskRow["Select"] = true;
        }
      }
    }

    private void button4_Click(object sender, EventArgs e)
    {
      DataTable table = dgv_Tasks.DataSource as DataTable;
      string filterString = table.DefaultView.RowFilter;
      foreach (DataRow row in table.Select(filterString))
      {
        row["Select"] = true;
      }
    }

    private void button3_Click(object sender, EventArgs e)
    {
      string filterString = "OutlineLevel ";
      switch (comboBox1.SelectedIndex)
      {
        case 0: filterString += "=";
          break;
        case 1: filterString += ">";
          break;
        case 2: filterString += ">=";
          break;
        case 3: filterString += "<";
          break;
        case 4: filterString += "<=";
          break;
      }
      filterString += numericUpDown1.Value.ToString();
      DataTable table = dgv_Tasks.DataSource as DataTable;
      table.DefaultView.RowFilter = filterString;
    }

    private void button6_Click(object sender, EventArgs e)
    {
      DataTable table = dgv_Tasks.DataSource as DataTable;
      string filterString = table.DefaultView.RowFilter;
      foreach (DataRow row in table.Select(filterString))
      {
        row["Select"] = false;
      }
    }

    private void button5_Click(object sender, EventArgs e)
    {
      DataTable table = dgv_Resources.DataSource as DataTable;
      foreach (DataRow row in table.Rows)
      {
        row["Select"] = true;
      }
    }

    private void button7_Click(object sender, EventArgs e)
    {
      DataTable table = dgv_Resources.DataSource as DataTable;
      foreach (DataRow row in table.Rows)
      {
        row["Select"] = false;
      }
    }

    private void styleTaskGrid()
    {
      foreach (DataGridViewRow taskRow in dgv_Tasks.Rows)
      {
        DataRowView taskView = taskRow.DataBoundItem as DataRowView;
        DataRow task = taskView.Row;
        Font summaryCellFont = new Font(dgv_Tasks.Font, FontStyle.Bold);
        DataGridViewCellStyle style = dgv_Tasks.DefaultCellStyle.Clone();
        style.Font = summaryCellFont;
        if ((bool)task["IsSummary"])
        {
          taskRow.Cells[3].Style = style;
        }
      }
    }

  }
}
